package com.gzedu.common.sys;

import java.util.ArrayList;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import com.gzedu.common.exception.MyException;
import com.gzedu.common.util.SystemConstants;
import com.gzedu.module.faced.meun.MeunFacade;
import com.gzedu.module.faced.user.UserFaced;
import com.gzedu.module.modle.meun.Meun;
import com.gzedu.module.modle.role.Role;
import com.gzedu.module.modle.user.User;

public class MyRealm extends AuthorizingRealm{
	//private static final Logger log = LoggerFactory.getLogger(MyRealm.class);  
    // 注入service  
    @Autowired  
    private UserFaced userFaced;  
    @Autowired
    private MeunFacade meunFacade;
    /**  
     * 为当前登录的Subject授予角色和权限  
     * @author jianfei  
     */  
    @Override  
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
        if (principals == null) {  
            throw new AuthorizationException(  
                    "PrincipalCollection method argument cannot be null.");  
        }  
        // 获取当前登录的用户名,等价于(String)principals.fromRealm(this.getName()).iterator().next()  
        String regName = (String) getAvailablePrincipal(principals);  
  
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
  
        List<String> roleList = new ArrayList<String>();  
        //用于存放权限信息  
        List<Meun> resourceList = new ArrayList<Meun>();  
        // //从数据库中获取当前登录用户的详细信息  
        User user = userFaced.getUserByName(regName);  
        if (null != user && null != user.getRoles()) {  
            //得到角色集合  
            List<Role> roles = user.getRoles();  
            //遍历角色  
            for(Role role : roles){  
                roleList.add(role.getRoleCode());  
                //查询权限如果是超级管理员取出所有权限  
                if(role.getRoleCode().contains(SystemConstants.SUPER_ADMIN_ROLE_CODE)){  
                    resourceList = meunFacade.getAll(); 
                    break;  
                }else{  
                    resourceList.addAll(meunFacade.findByRoleCode(role.getRoleCode()));  
                }  
            }  
            info.addRoles(roleList);  
        } else {  
            throw new AuthorizationException();  
        }  
        if(resourceList != null && resourceList.size() > 0){  
            //权限集合  
            List<String> perList = new ArrayList<String>();  
            //遍历资源，取出权限集合  
            for(Meun m : resourceList){  
                String pre = m.getUrl();  
                if(null != pre && !pre.equals("")){  
                    perList.add(pre);  
                }  
            }  
            //遍历权限集合取出权限  
            for(String perStr:perList){  
               
	             if (perStr!=null && !"".equals(perStr.trim()))  
	                 info.addStringPermission(perStr);  
	//                      System.out.println("该用户下拥有权限："+str);  
                 
            }    
        }  
        return info;  
    }  
  
    /**  
     * 用户登录权限认证  
     * @author jianfei  
     */  
    @Override  
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) {  
        // 获取基于用户名和密码的令牌  
        // 实际上这个authcToken是从LoginController里面currentUser.login(token)传过来的  
        // 两个token的引用都是一样的  
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;  
        //从token中获取用户名  
        String userName = token.getUsername();  
        if (userName != null && !"".equals(userName)) {  
            User user = userFaced.getUserByName(userName);  
            if(null != user){    
                SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userName, user.getPassword(), getName());  
                if (getCredentialsMatcher().doCredentialsMatch(token,authenticationInfo)){  
                    //用户信息存入session  
                    Subject currentUser = SecurityUtils.getSubject();  
                    currentUser.getSession().setAttribute("loginUser", user);  
                    //如果缓存存在权限信息则清空  
                    Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();  
                    if (cache != null) {  
//                        if (log.isTraceEnabled()) {  
//                            log.trace("Attempting to retrieve the AuthorizationInfo from cache.");  
//                        }  
                        cache.remove(userName);  
                    }  
                    return authenticationInfo;  
                }else{  
                    try {
						throw new MyException("密码不正确");
					} catch (MyException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}  
                }  
            }else{  
                try {
					throw new MyException("用户不存在");
				} catch (MyException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}  
            }  
        }else{  
            try {
				throw new MyException("用户名不能为空");
			} catch (MyException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}  
        }
		return null; 
    }  
}
